Printers can cause quite a few problems for system administrators because the
configuration and handling of a printer under Linux is considerably different than under
DOS or OS/2. The unintuitive nature of the printer commands also complicates the handling
of printers and print systems. Despite these quibbles, printers are quite easy to
configure as long as you know a little about Linux, device drivers, and the printers you
are using. Managing the printer queues is also relatively easy, but like many things in
Linux, you must know the tricks to make the system work for you.
The printing capabilities of Linux are not as powerful and easy-to-use as most
commercial versions of UNIX. Linux is based on BSD UNIX, which is not the most talented
version with respect to printer administration. Luckily, few users use more than one or
two printers in a typical parallel-port or serial-port based installation, so
administration requirements are simplified enormously. When you work with large networked
printer environments, however, Linux's limitations in this area are more apparent. A word
of warning: Linux's printer administration routines have a reputation for quirky behavior,
such as suddenly stopping the print spooler for no apparent reason!
Linux supports both parallel and serial printers, as well as network printers
(available from another machine on the local area network). Most parallel and serial
printers are character mode devices, although a few high-speed printers are block mode
devices (although block mode printers are usually much too expensive for a small
Linux-based system). Unfortunately, Linux does not have a simple-to-use printer
installation and configuration utility like many UNIX versions, so you must create printer
devices and files manually. (A few printer installation and configuration scripts are
beginning to appear, although they are not in general use yet.)
Parallel printers are referred to as devices /dev/lp0, /dev/lp1, or /dev/lp2, depending
on the number of the parallel port with which they are used. Most printers attached to a
PC parallel port are attached to /dev/lp0, the first parallel device.
| Parallel port device | I/O address | DOS equivalent |
| /dev/lp0 | 0x03bc | LPT1 |
| /dev/lp1 | 0x0378 | LPT2 |
| /dev/lp2 | 0x0278 | LPT3 |
To determine the address of a parallel port, you can use a diagnostic utility (such as DOS' MSD.EXE or Norton Utilities). Some BIOS versions display port addresses when the system is booting. If you are unsure what the address is, try the parallel ports in order, starting with /dev/lp0, and see whether a printout is possible from that port.
Linux uses the mknod (make node) command to create a parallel printer device. The
command to make a parallel printer device on the first parallel port (/dev/lp0) is
mknod -m 620 /dev/lp0 c 6 0
In this example, the device /dev/lp0 is created as a character mode device with major
device number six and minor device number zero. (See Chapter 6,
"Devices and Device Drivers" for more information about device drivers and
device numbers.) Usually, minor device numbers start at zero and are incremented upwards.
Because this printer is the first one added, the minor device number is set to zero. The
-m option sets the file permission mask (to 620 in this case).
After you create the printer device driver file, you must change the ownership of the
device driver to root, daemon, or root.daemon. The owner root is a good default value, but
root.daemon is better because it adds a little more security to the ownerships by setting
the owner to root and the group to daemon with a single command:
chown root.daemon /dev/lp0
After changing the ownership of the file, check the file permissions. Set them to mode
620 by using the following command:
chmod 620 /dev/lp0
The ownership root.daemon is a special Linux convention for the daemons run by root. The entry root.daemon does not appear in the /etc/passwd file, but it is legal. This syntax sets the owner and group at the same time. The owner is the first part of the entry, and the group follows a period. The entry root.daemon sets the owner to root and the group to daemon.
To configure a device other than the first parallel port (/dev/lp0), you must change
the device name itself to the device number. For each possible parallel port, the mknod
commands are as follows:
mknod -m 620 /dev/lp0 c 6 0 mknod -m 620 /dev/lp1 c 6 1 mknod -m 620 /dev/lp2 c 6 2
In these examples, the minor device numbers have been incremented to correspond to the
port number. Although numbering the devices in this manner is not absolutely necessary, it
can help with identification when you want to know which port the device is hanging off
of.
After issuing the mknod and chown commands, check to ensure that the ownerships are set
properly. You should also create a spool directory for the printer. The permissions and
ownership requirements of the spool directory are important and are discussed in "The
/etc/printcap File" section later in this chapter.
Printing services are handled by a daemon called lpd (line printer daemon). The lpd
daemon is usually started automatically in the /etc/rc boot process when the system moves
to multiuser mode. The lpd daemon handles a number of tasks and keeps running as long as
Linux is active (unless terminated by the superuser or a daemon crash). One of the
important parts of the daemon's startup procedures is to read the printer configuration
file, /etc/printcap.
The /etc/printcap file is used to identify instructions for communicating with all the
printers that are configured and attached to the system (in the same manner that
/etc/termcap contains terminal definitions). Once it has started itself, lpd starts up two
other daemons called listen and accept that handle any incoming print request.
You probably won't ever have to modify the lpd daemon. Because the Linux daemon is a
little unstable, though, you may have to restart or terminate it while you make some
configuration changes. To start the lpd daemon, use this syntax:
lpd [-l] [port]
The -l option starts a logging process that copies a note to a log file every time a
print request is handled. Although the -l option can be useful when you're debugging a
printer installation or configuration, be careful about leaving it running for too
longthe log files tend to become very large. If you do keep logging active, use a
cron process to clean the log file at regular intervals.
The port option of the lpd command enables you to specify an Internet port number for
the daemon if you want the system default information to be ignored. You will probably
never have to use this option on a stand-alone or small network, but it can be useful with
very large networked printing systems (which are unlikely to be based on Linux).
When a print request is received over the network (or locally), the lpd daemon performs
a short validation routine to see whether the user who sent the request is allowed to use
the printer. This routine uses the /etc/hosts.equiv and /etc/hosts.lpd files. If the
machine name of the sending user is not in either file, the print request is refused. Your
local machine is always in hosts.equiv (as localhost), so all users on your machine can
have their print requests granted.
If you have to terminate the lpd daemon, obtain its process ID number using the ps
command, and then issue a kill command with that process number. Chapter
20, "Processes," explains these steps in more detail. When the lpd daemon is
terminated, no print requests are accepted.
When a print request (often called a print job) is received by lpd (or its associated
listen and accept processes), the pages to be printed are copied to another area, called
the print spool area, of the filesystem. This action frees up your console when you issue
a print request and enables you to continue to make changes to the files you want to print
after they have been sent to the daemon.
In most cases, the print spool area is in the /usr/spool/lp directory. Under this spool
directory, each installed printer has a dedicated directory, which is usually given the
printer's name specified during the printer installation routine. For example, a printer
called hplaser uses the spool directory /usr/spool/hplaser. All the print requests for
each printer are stored in its directory. In this directory, each request is assigned a
unique filename and a print request identification number. The daemon for this printer
adds the print request number to a queue and notifies you of what the number is. You can
then use the print request identification number to check the status of the print request
or remove the request from the queue.
Some versions of Linux let you set the size of the print spool area though an entry in
the minfree file in the spool directory. The minfree file gives the number of disk blocks
(usually a block is 1K) set aside for spooling requests. You can change the minfree file
with any ASCII editor. If you have lots of disk space, you needn't worry about this value
because the spooler will use available space as necessary. If you are tight for disk
space, though, you may want to reserve a little space for the spooler that can't be used
for other reasons. The size of the disk space reserved for the spooler should be dependent
on the number of users and the amount of printing they will do. A good rule of thumb is
about 100K per user for normal use.
Each printer's spool directory may contain two special files called status and lock.
Each file is one line long and can be modified with an ASCII editor. The files contain a
description of the current state of the printer. The lpd daemon creates and manages these
files, which several printer commands use display status information to the user.
This section follows a typical print request through the print system so you can see
how the printer daemons work and how Linux handles each stage of the request. When you
issue a print request with a print command (such as lpr), the command generates output for
the printer to print. The command then copies that output into the queue in the spool
directory for the printer you have requested.
You can specify the printer destination on the print command line or set a default
printer name as an environment variable so the system always knows which printer to use.
After determining the destination printer name, lpr checks the file /etc/printcap for the
printer's configuration information (including the spool directory name).
The lpr program is the only one in the Linux system that can queue files for printing. Any other program that offers printing capabilities, including most editors and word processors, executes the print request by calling lpr.
As part of the spooling task, lpr checks for any special instructions on how to print
the file. These instructions may refer to fonts, paper sizes, colors, processing
languages, or any other printer configuration information. Printer instructions can come
from the command line (in the form of arguments you provide with the print command), from
environment variables (set up by the shell's startup files or you), or from the system's
default values.
When the print request is copied into the spool directory, lpr creates two files. One
file has the letters cf (control file) followed by the print ID number. This cf file
contains information about the print job, including the owner's name and special printing
instructions such as line spacing or paper selection. The other file starts with the
letters df (data file) and holds the contents of the file to be printed. After lpr creates
the df file, it sends a signal to the lpd daemon that indicates that a print job is
waiting in the spool directory. The lpd daemon then starts a daemon to handle the
printer's queue (if one isn't already running). A daemon is present for every printer
queue as long as there is something to print. When the print queue is empty, the printer
daemon terminates.
After lpd gets the print job signal from lpr, it checks the file /etc/printcap to see
whether the printer is a local or remote printer. For remote printers (one attached to
another machine on the network), lpd starts a network connection to the remote machine and
transfers both the control and data files to the remote's spool directories and informs
the remote machine's lpd daemon that a print request is queued. To end the process for a
remote print request, lpd deletes the local copies of the cf and df files. For local
printer requests, lpd checks to make sure the printer exists and is enabled, and then
sends the print request to the daemon running that printer queue. Once the files have been
printed, they are deleted from the spool directories.
As you have seen already in this section, the /etc/printcap file is used by both the
print commands (such as lpr) and the lpd daemon. The /etc/printcap file contains
information about every printer that is accessible from the Linux machine, including all
remote printers that have been configured on the local machine. The following extract from
the /etc/printcap file for the Hewlett Packard LaserJet 4M laser printer shows the
straightforward format of this kind of file:
# HP Laserjet lp|hplj|hplaserj-tparker|HP LaserJet 4M next to the water fountain:\ :lp=/dev/lp0:\ :sd=/usr/spool/lp/lp0:\ :lf=/usr/spool/lp/errorlog:\ :mx#0:\ :of=/usr/spool/lp0/hpjlp:\
Comments anywhere in the information are identified by a pound sign (also called a hash
mark) in the first column. The first field in each printer's entry is a list of all the
names users can use to refer to the printer. These names can be used with environment
variables and as options on the lpr command line. All the valid printer names are
separated by a vertical bar. Usually each entry has at least three names: a short name
that is four characters or less (such as hplj), a more complete name with an owner, if
necessary (such as hplaser-tparker), and a full descriptive name with any other
information necessary to identify the printer to a user (such as HP LaserJet 4M next to
the water fountain).
If a print job is submitted without a destination name and one cannot be determined from environment variable values, the job is routed to the Linux system default printer name lp. Therefore, one of the printers (usually the system default printer) should also have the name lp as part of its identifying names in order to prevent error messages.
Following the printer name is a set of two-character parameters and values used to
define configuration information about the printer. The format of these entries follows
one of the following models:
| NN | A Boolean value |
| NN=string | Set equal to string |
| NN#number | Set not equal to number |
Most assignments in this area of the /etc/printcap file are shown with colons beginning
and ending each definition to enhance readability (and make the file easier for the print
utilities to parse for information). Null values are allowed; you can create them by
putting two colons together with no space between them.
When you use a Boolean value (with no assignment following the two character
identifier), the value is set to True by default. If you want the vaule to be False, don't
include the two-character identifier in the description. You use Booleans to specify
simple information, such as printer control language support.
As with terminal definitions in the /etc/termcap file, many codes are allowed in the
/etc/printcap file. A few of the more important and prevalent parameters are worth
mentioning as they are useful for administration purposes:
| sd | The spool directory |
| lf | The log directory for error messages |
| af | Accounting log file |
| mx | What type of files can be printed |
| of | Output filter program to be used when printing |
Not all these parameters need to be present in every printer definition in the
/etc/printcap file, but they are likely to be present as they provide basic information.
The sd parameter specifies the spool directory for the printer. As mentioned earlier,
all printers should have their own spool directories. The spool directories are usually
composed by taking the printer name and creating a directory with that name under the
/usr/spool directory, such as /usr/spool/lp/hplj and /usr/spool/lp/epson. Spool
directories are necessary for both remote and local printers.
When you add a new printer is added to the system, you may have to create a spool directory manually by using mkdir. Set the permissions for the spool directory to 775. The directory must be owned by root or daemon, and you should set the group ID to root or daemon as well. In both cases, daemon is arguably the better ID for user and group, although root works fine (but may pose a very slight security problem).
The lf parameter specifies the log directory for error messages. You can put the
printer error log file anywhere on the system, although most Linux systems have it in the
/usr/spool/lp directory for easy access. All printers can share the error log, as each log
entry includes the name of the printer. Putting all the error messages in one directory
makes it easier to clean up the log files on a regular basis.
A printer accounting log file, as specified by the parameter af, is used to record the
number of printouts sent by a user on systems where users are charged for printing. When
an accounting file is used, an entry is written to the accounting log file after a print
job is finished. If the system doesn't use accounting records (most Linux systems don't),
you can ignore the accounting log file entry in the /etc/printcap file, although you may
want to have the accounting file active for statistical purposes. You can display account
information with the Linux pac command. Use the man pac command to display the man pages
for more information about pac.
The mx parameter enables you to identify the types of files to be printed. Usually this
parameter is set to mx#0, meaning that there are no restrictions on the types of files.
You may want to restrict the type of printing on some lasers or inkjets that have high per
page costs, for example, or prevent pages with color instructions from being printed as
grayscales on a monochrome laser printer.
You use output filters, specified by the parameter of, to modify the format of the
outgoing print file to fit the printer. For example, a common output filter changes the
number of lines per page. Many laser printers can't handle 66 lines per page, so the
output filter repaginates output to 60 lines per page (or whatever the number of lines per
page is set to). Sometimes special codes must be added to force line feeds, font changes,
or paper bin selections. All these items are part of the output filter. Several other
types of filters are available, but the output filter is the most common.
Linux systems control printers through a utility called lpc. The lpc program enables
you to do several important functions involving the printers on your Linux system:
You cannot use the lpc program for remote printers. It only affects those printers
directly attached and configured on the local machine. If you must manage a remote
printer, log into the remote machine as root and make the changes through that login.
The lpc utility is one of the most unpredictable and unreliable programs included with the Linux operating system. It can hang up for no obvious reason and can display faulty status messages.
When executed on the command line without any arguments, lpc prompts you for a command.
The following list summarizes all the valid lpc commands and their arguments (a vertical
bar indicates a choice of arguments):
The lpc utility is not very user-friendly, but it is the only way to handle the
printers and their queues in Linux. Several front-end menu-driven utilities are beginning
to appear that simplify this task, but they are of variable quality and are not widely
available.
Instead of totally relying on the lpc command, you can use the several commands that help you administer the printer queue directly. These commands are designed to simplify the two tasks that are commonly required by a system administrator: displaying the current queue and removing print jobs in a queue.
To display the current print queue for any printer, use the lpq command. It has the
following syntax:
lpq [-l] [-Pprinter_name] [job_ID ...] [username ...]
With no arguments, lpq displays information about the current printer queues. The lpq
command normally displays information about who queued the print job, where it is in the
queue, the files being printed, and the total size of the files. The -l option displays
more information about each entry in the printer queue. Usually only one line of
information is displayed.
You can display a specific printer with the -P option followed by the printer's name.
If no name is supplied, the default system printer is displayed. If one or more job_IDs or
usernames are provided, only information about the specified jobs or jobs queued by the
specified user is shown.
To remove files from a printer queue, use the lprm command. This command is often
mistyped as lpr, which does not remove the file from the queue. To use lprm, you must know
the print job ID, or, if you are logged in as root, you can remove all jobs for a
particular printer. The syntax of the lprm command is as follows:
lprm [-Pprinter_name] [-] [job_ID ...] [username ...]
If the single hyphen argument is used, lprm removes all jobs owned by the user who
issues the command. If you are logged in as root and issue this command, all print jobs
are removed.
You can remove a particular printer's jobs by using the -P option. For example, the
command
lprm -Phplj -
removes all print jobs queued on the printer hplj by the user who issues the command or
all print jobs for that printer if the command is issued by root. If a print job ID or a
username is supplied as an argument, lprm removes the specified job or all jobs submitted
by the specified user. If no arguments are supplied, the currently active job submitted by
the user is deleted.
It is easy to accidentally remove all print jobs for a printer when you use the lprm command while logged in as root. Take care to use the proper syntax.
When lprm removes files from the queue, it echoes back a message to the display. If
there are no files to remove, nothing is echoed back (and you will be left wondering what,
if anything, happened).
Because users cannot access the Linux printer spooling directories, they can only remove queued print jobs with the lprm command. If you are a system administrator, you may want to let all system users know how to use this command to save unwanted print jobs from printing.
If you try to use lprm on a job that is currently being printed, it may not be
terminated properly as the file may already reside in the printer's buffer. In some cases,
terminating a job that is currently printing can cause the printer to lock because some
output format files cannot handle the termination instructions and freeze when the lock
file in the spool directory changes. In cases like this, you must use the ps command to
find the output filter process ID and then kill that filter.
When you have a printer lockup problem that doesn't solve itself when you use the lpc utility, try killing the lpd daemon and restarting it. If that doesn't work, you probably have to reboot the entire system.
Handling printers on a Linux system is not onerous, as long as you know the commands and processes that perform the daily tasks you need. Installing the printer is quite easy, although you have to be careful to set the permissions and ownerships properly. Once installed, printers tend to be either trouble-free or troublesome. All you can do is hope for the former!